package estoque;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import pessoa.Fornecedor;
import pessoa.RepositorioCliente;
import pessoa.RepositorioFornecedor;

import database.Database;
import excecoes.CodigoInvalidoException;
import excecoes.CpfCnpjInvalidoException;
import excecoes.ValorNegativoException;


/**
 * Esta classe e responsavel por manter os produtos, executando as operacoes de  efetuar, excluir,
 *  alterar, pesquisar e recuperar-los
 * 
 */
public class Estoque {

	private Connection conexao;

	/**
	 * Esse construtor atribui uma conexao ao atributo conexao da classe
	 */
	public Estoque(){

		conexao = Database.getConexao();

	}

	/**
	 * Esse metodo deve cadastrar um produto, registrando-o no banco de dados
	 * 
	 * @param produto a ser cadastrado
	 */
	public void cadastrar(Produto produto){

		if(produto == null){
			throw new RuntimeException();
		}
		
		String sql = "INSERT INTO produto (nome, taxa_juros, preco_venda, preco_custo," +
				"data_entrada, data_vencimento, quantidade, cnpj_fornecedor) " +
				"VALUES (?,?,?,?,?,?,?,?);";

		try{

			PreparedStatement statement = conexao.prepareStatement(sql);
			
			
			statement.setString(1, produto.getNome());
			statement.setDouble(2, produto.getTaxa_juros());
			statement.setDouble(3, produto.getPreco_venda());
			statement.setDouble(4, produto.getPreco_custo());
			statement.setDate(5, produto.getData_entrada());
			statement.setDate(6, produto.getData_vencimento());
			statement.setDouble(7, produto.getQuantidade());
			statement.setString(8, produto.getFornecedor().getCnpj());
			

			statement.execute();
			statement.close();

		}catch (SQLException e) {

			e.printStackTrace();

			throw new RuntimeException("Falha ao cadastrar produto");

		}
	}

	/**
	 * Esse metodo deve excluir um produto, excluindo-o do banco de dados.
	 * 
	 * Um produto nao pode ser excluido se ele tiver alguma venda.
	 */
	public void excluir(){

	}

	/**
	 * Esse metodo deve atualizar os atributos de um produto
	 * 
	 * Um produto nao pode ser alterado se ele tiver alguma venda.
	 * Nao se deve alterar o codigo do produto
	 */
	public void atualizar(){

	}

	/**
	 * Esse metodo deve pesquisar um produto no banco de dados e retorna-lo
	 * 
	 * @param codigo
	 * 
	 * @throws CodigoInvalidoException - se o codigo for menor que 0 
	 * 
	 * @return um objeto Produto, ou null caso o codigo nao seja econtrado
	 */
	public Produto pesquisar(int codigo) throws CodigoInvalidoException{
			
		/*
		 * Se o codigo for menor do q 0, ele e invalido
		 */
		if(codigo < 0){

			throw new CodigoInvalidoException("Codigo Invalido");

		}
		
		Produto produto = null;

		for(Produto P : recuperarProdutos()){
			
			if(P.getCodigo() == codigo){
				
				produto = P;
				
			}
			
		}
		
		return produto;

	}//pesquisar()

	/**
	 * Esse metodo deve retornar todos os produtos contidos no banco de dados
	 */
	public ArrayList<Produto> recuperarProdutos(){
		
		ArrayList<Produto> produtos = new ArrayList<>();

		try {

			String sql = "SELECT * FROM produto;";
			
			PreparedStatement statement = conexao.prepareStatement(sql);
			
			ResultSet result = statement.executeQuery();

			/*
			 * recupera todos os dados da tabela, transfere para um objeto fornecedor
			 * e adiciona o objeto no arraylist
			 */
			while(result.next()){
				
				RepositorioFornecedor repositorio =  new RepositorioFornecedor();
				
				Fornecedor fornecedor = repositorio.pesquisar(result.getString("cnpj_fornecedor"));
				
				produtos.add(new Produto(result.getInt("codigo"), result.getString("nome"),
						result.getInt("quantidade"), fornecedor, result.getDouble("preco_venda"),
						result.getDouble("preco_custo"), result.getDouble("taxa_juros"),
						result.getDate("data_entrada"), result.getDate("data_vencimento")));

			} 

			/*
			 * Fecha o ResultSet e o Statement
			 */
			result.close();
			statement.close();

		} catch (SQLException e) {

			e.printStackTrace();
			
			throw new RuntimeException("Falha ao recuperar produtos");

		}
		
		return produtos;
		
	}//recuperarProdutos()

	/**
	 * Esse metodo serve para verificar se um determinado fornecedor tem produto
	 */
	public boolean temProduto(String cnpj){
		
		boolean resultado = false;
		
		for(Produto P : recuperarProdutos()){
			
			if(P.getFornecedor().getCnpj().equals(cnpj)){
				
				resultado = true;
				
			}
		}
		
		return resultado;

	}


}
